package com.autoerp;

import java.sql.Connection;
import java.util.Locale;
import org.mentabean.BeanSession;
import org.mentabean.DBTypes;
import org.mentabean.util.SQLUtils;
import org.mentawai.core.ApplicationManager;
import org.mentawai.core.Props;
import org.mentawai.db.ConnectionHandler;
import org.mentawai.db.mysql.MySQLBoneCPConnectionHandler;
import org.mentawai.filter.ExceptionFilter;
import org.mentawai.filter.MentaContainerFilter;
import org.mentawai.filter.TransactionFilter;
import org.mentawai.mail.Email;
import com.kenai.jaffl.mapper.FunctionMapper.Context;


import com.autoerp.action.UsuarioAction;
import com.autoerp.dao.UsuarioDAO;
import com.autoerp.dao.jdbc.UsuarioDAOJdbc;
import com.autoerp.model.administracao.*;

// TODO: Auto-generated Javadoc
/**
 * Classe responsavel pelas configuracoes globais.
 */
public class ConfigManager extends ApplicationManager {

	/**
	 * Acesso ao arquivo de configuracao da aplicacao
	 */
	private Props props;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mentawai.core.ApplicationManager#init(org.mentawai.core.Context)
	 */
	public void init(Context application) {

		// Obter o arquivo de configuracao da aplicacao
		this.props = getProps();

		// Configurar o modo de depuracao da aplicacao
		setDebugMode(props.getBoolean("debug_mode"));

		// Configurar a atualizacao automatica da aplicacao
		setReloadable(props.getBoolean("auto_reload"));

		// Setar o padrao de codificacao dos caracteres utilizados pela
		// aplicacao
		this.setReqCharEncoding("UTF-8");

		// Configurar o envio de e-mail da aplicacao
		if (!props.getBoolean("email.send_email")) {

			Email.setSendEmail(false);

		} else {

			Email.setDefaultHostName(props.getString("email.host"));

			Email.setDefaultSslConnection(props.getBoolean("email.ssl"));

			Email.setDefaultPort(props.getInt("email.port"));

			if (props.getBoolean("email.use_authentication")) {

				Email.setDefaultAuthentication(props.getString("email.user"),
						props.getString("email.pass"));
			}

			Email.setDefaultFrom(props.getString("email.from_email"),
					props.getString("email.from_name"));
		}
	}

	//@Override
	public ConnectionHandler createConnectionHandler() {

		// Obter o driver utilizado pelo banco de dados
		String driver = props.getString("jdbc.driver");

		// Obter a url de conexao ao banco de dados
		String url = props.getString("jdbc.url");

		// Obter o login da conexao ao banco de dados
		String user = props.getString("jdbc.user");

		// Obter a senha da conexao ao banco de dados
		String pass = props.getString("jdbc.pass");

		// Realizar a conexao ao banco de dados
		return new MySQLBoneCPConnectionHandler(driver, url, user, pass);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mentawai.core.ApplicationManager#setupDB()
	 */
	@Override
	public void setupDB() {

		// Inicializa a conexao ao banco de dados
		initDatabaseIfNeeded();

	}

	@Override
	public void loadFilters() {

		// Adicionar o filtro de excecao
		filter(new ExceptionFilter());
		on(EXCEPTION, fwd("/jsp/error.jsp"));

		// Adicionar o filtro MentaContainerFilter, responsavel pelo padrao
		// Inversion of Control
		filter(new MentaContainerFilter());

		// filter(new AuthenticationFilter());
		// on(LOGIN, redir("/jsp/login.jsp"));

		// filter(new ValidationFilter());

		// Adicionar o filtro de transacao
		filter(new TransactionFilter());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mentawai.core.ApplicationManager#loadLocales()
	 */
	@Override
	public void loadLocales() {

		// Adicionar o locale brasileiro
		addLocale(new Locale("pt", "BR"));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mentawai.core.ApplicationManager#setupIoC()
	 */
	@Override
	public void setupIoC() {

		// Adicionar o gerenciador da sessao do bean
		ioc(BeanSession.class, props.getClass("mentabean.dialect"));

		// IoC componentes (DAOs)
		ioc(UsuarioDAO.class, UsuarioDAOJdbc.class);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mentawai.core.ApplicationManager#loadBeans() Metodo do mentawai
	 * para mapeamento objeto-relacional diretamente com código Java
	 */
	@Override
	public void loadBeans() {

		// Mapeando a tabela "tb_usuario" para o bean do modulo USUARIO
		bean(UsuarioEntity.class, "tb_usuario")

		.pk("id_usuario", DBTypes.AUTOINCREMENT)
				.field("de_usuario", DBTypes.STRING)
				.field("de_login", DBTypes.STRING)
				.field("de_senha", DBTypes.STRING)
				.field("id_grupo", DBTypes.INTEGER);

	}

	@Override
	public void loadActions() {
		
		// Registro da acao ADICIONAR USUARIO
		action("/Usuario", UsuarioAction.class, "adicionar").on(CREATED,
				fwd("/jsp/usuario/editar.jsp"));
		
	}

private void initDatabaseIfNeeded() {
		
		final ConnectionHandler connHandler = getConnectionHandler();
		
		connHandler.exec(new ConnectionHandler.Exec() {
		
			@Override
			public void exec(Connection conn) {
				initDatabaseIfNeeded(conn);
			}
		});
	}
	
	protected void initDatabaseIfNeeded(Connection conn) {
		
		if (SQLUtils.checkIfTableExists(conn, "tb_usuario")) return;
		
		try {
			String file = props.getAbsolutePath("db.script");
			SQLUtils.executeScript(conn, file, "UTF-8");
		} catch(Exception e) {
			e.printStackTrace();
		}

		if (!SQLUtils.checkIfTableExists(conn, "tb_usuario")) throw new RuntimeException("Falha ao inicializar db!");
	}
}